package com.cn.jinl.service;

import com.alibaba.fastjson.JSONObject;
import com.cn.jinl.api.IMeterPowerService;
import com.cn.jinl.api.ISysItemService;
import com.cn.jinl.dao.MeterPowerMapper;
import com.cn.jinl.domain.MeterPower;
import com.cn.jinl.domain.MeterPowerExample;

import com.cn.jinl.domain.MeterPowerInit;
import com.cn.jinl.domain.SysItem;
import com.cn.jinl.utils.CommonUtil;
import com.cn.jinl.utils.NumberUtil;
import com.cn.jinl.utils.QueryForm;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.omg.CORBA.INTERNAL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class MeterPowerServiceImpl implements IMeterPowerService {

    @Autowired
    private MeterPowerMapper meterPowerMapper;

    @Autowired
    private ISysItemService sysItemService;

    public static final transient Map<String, Integer> BeiShuMap =
            ImmutableMap.of("净化", 80, "南仓", 160,"直管",80,"办公",30);

    @Override
    public Map<String, List<JSONObject>> getMeterPowerList(QueryForm queryForm) throws Exception {
        Map<String, List<JSONObject>> results = Maps.newLinkedHashMap();
        List<String> meterTypes = Lists.newArrayList("5");
        QueryForm itemQuery = new QueryForm();
        itemQuery.setTypes(meterTypes);
        List<SysItem> sysItems = sysItemService.getMgItemSelect(itemQuery);
        if (CollectionUtils.isEmpty(sysItems)) {
            return results;
        }

        MeterPowerExample sumExample = new MeterPowerExample();
        sumExample.createCriteria().andYearEqualTo(queryForm.getMeterYear()).andMothEqualTo(queryForm.getMeterMoth());
        sumExample.setOrderByClause("time1 asc");
        List<MeterPower> meterPowers = meterPowerMapper.selectByExample(sumExample);
        List<JSONObject> headers = Lists.newLinkedList();
        JSONObject rq = new JSONObject();
        rq.put("columnValue", "time");
        rq.put("columnName", "日期");
        headers.add(rq);
        List<String> registerMeters = Lists.newArrayList();

        Map<String,Integer> codeBeishuMaps = Maps.newHashMap();
        for (SysItem sysItem : sysItems) {
            String itemName = sysItem.getItemName();
            String aliasName = sysItem.getItemAlias();
            String header = itemName + " " + aliasName;
            JSONObject column = new JSONObject();
            column.put("columnValue", aliasName);
            column.put("columnName", header);
            headers.add(column);
            registerMeters.add(aliasName);
            if(BeiShuMap.containsKey(itemName)){
                codeBeishuMaps.put(aliasName,BeiShuMap.get(itemName));
            }
        }
        JSONObject total = new JSONObject();
        total.put("columnValue", "total");
        total.put("columnName", "合计");
        headers.add(total);
        Map<String, List<MeterPower>> meterMaps = Maps.newLinkedHashMap();
        for (MeterPower meterPower : meterPowers) {
            String time1 = meterPower.getTime1();
            String sn = meterPower.getSn();
            if (!registerMeters.contains(sn)) {
                continue;
            }
            if (meterMaps.containsKey(time1)) {
                meterMaps.get(time1).add(meterPower);
            } else {
                List<MeterPower> powers = Lists.newLinkedList();
                powers.add(meterPower);
                meterMaps.put(time1, powers);
            }
        }

        List<JSONObject> datas = Lists.newLinkedList();
        for (String key : meterMaps.keySet()) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("time", key);
            List<MeterPower> pws = meterMaps.get(key);
            double totalPa = 0.000;
            for (MeterPower pw : pws) {
                double paAdd = Double.parseDouble(pw.getPaAdd());
                if(codeBeishuMaps.containsKey(pw.getSn())){
                    paAdd = codeBeishuMaps.get(pw.getSn())*paAdd;
                }
                totalPa += paAdd;
                jsonObject.put(pw.getSn(),  NumberUtil.getPoint(paAdd, 2));
            }
            jsonObject.put("total", NumberUtil.getPoint(totalPa, 2));
            datas.add(jsonObject);
        }
        results.put("header", headers);
        results.put("list", datas);
        return results;
    }

    @Override
    public String addMeterPower(JSONObject jsonObject) throws Exception {
        List<String> attrs = Lists.newArrayList("SN", "Madd", "Snum", "Time1", "Tp", "Pa", "Pa1", "Pa2", "Pa3", "Pa4", "Rp", "R1p", "R2p", "Maxd", "IFP", "Tf", "Fr");
        MeterPower add = new MeterPower();
        int count = 0;
        for (String attr : attrs) {
            String value = jsonObject.getString(attr);
            if (StringUtils.isNotEmpty(value)) {
                if (StringUtils.equals("Time1", attr)) {
                    String year = value.split("-")[0];
                    add.setYear(year);
                    add.setMoth(value.split("-")[1]);
                    add.setDay(value.split("-")[2]);
                }
                String firstA = attr.substring(0, 1).toUpperCase();
                String setMethod = "set" + firstA + attr.toLowerCase().substring(1);
                Method setNameMethod = add.getClass().getMethod(setMethod, String.class);
                setNameMethod.invoke(add, value);
            }
        }
        if (StringUtils.isNotEmpty(add.getTime1())) {
            String code = add.getSn();
            MeterPower lastOneData = meterPowerMapper.selectLastOneMeterPowerBySn(code);
            int existCount = 0;
            if(null == lastOneData){
                //初始化电量
                List<MeterPowerInit> meterPowerInits = meterPowerMapper.selectLastMeterPower();
                for (MeterPowerInit powerInit : meterPowerInits) {
                    if(StringUtils.equals(powerInit.getSn(),code)){
                        double pa_add = Double.parseDouble(add.getPa()) - Double.parseDouble(powerInit.getValue1());
                        String paStr = NumberUtil.getPoint(pa_add, 2);
                        add.setPaAdd(paStr);
                    }
                }
            }else{
                String time1 = lastOneData.getTime1();
                if(StringUtils.equals(time1,add.getTime1())){
                    existCount = 1;
                    double pa_add = Double.parseDouble(add.getPa()) - Double.parseDouble(lastOneData.getPa())+ Double.parseDouble(lastOneData.getPaAdd());
                    String paStr = NumberUtil.getPoint(pa_add, 2);
                    add.setPaAdd(paStr);
                }else{
                    double pa_add = Double.parseDouble(add.getPa()) - Double.parseDouble(lastOneData.getPa());
                    String paStr = NumberUtil.getPoint(pa_add, 2);
                    add.setPaAdd(paStr);
                }
            }
            MeterPowerExample sumExample = new MeterPowerExample();
            sumExample.createCriteria().andTime1EqualTo(add.getTime1()).andSnEqualTo(add.getSn());
            if (existCount > 0) {
                count = meterPowerMapper.updateByExampleSelective(add, sumExample);
            } else {
                count = meterPowerMapper.insertSelective(add);
            }
            if (count < 1) {
                throw new Exception("插入电表异常！");
            }
        }
        return CommonUtil.outStr(count);
    }



    @Override
    public Map<String, List<MeterPower>> getYearMeterPowers(String year) throws Exception {
        List<String> meterTypes = Lists.newArrayList("5");
        QueryForm itemQuery = new QueryForm();
        itemQuery.setTypes(meterTypes);
        List<SysItem> sysItems = sysItemService.getMgItemSelect(itemQuery);
        if (CollectionUtils.isEmpty(sysItems)) {
            return Maps.newHashMap();
        }
        List<MeterPower> meterPowers = meterPowerMapper.selectYearMeterPowers(year);
        Map<String, List<MeterPower>> meterPowerMap = Maps.newLinkedHashMap();
        for (MeterPower meterPower : meterPowers) {
            String key = meterPower.getSn();
            if (meterPowerMap.containsKey(key)) {
                meterPowerMap.get(key).add(meterPower);
            }else{
                List<MeterPower> list = Lists.newLinkedList();
                list.add(meterPower);
                meterPowerMap.put(key,list);
            }
        }
        Map<String, List<MeterPower>> results = Maps.newLinkedHashMap();
        for (SysItem sysItem : sysItems) {
            List<MeterPower> yearDatas = meterPowerMap.get(sysItem.getItemAlias());
            List<MeterPower> datas = Lists.newLinkedList();
            Map<String,String> meterMothMap = Maps.newHashMap();
            if(!CollectionUtils.isEmpty(yearDatas)){
                for(MeterPower meter:yearDatas){
                    double paAdd = Double.parseDouble(meter.getPaAdd());
                    if(BeiShuMap.containsKey(sysItem.getItemName())){
                        paAdd = BeiShuMap.get(sysItem.getItemName())*paAdd;
                    }
                    meterMothMap.put(meter.getMoth(), NumberUtil.getPoint(paAdd, 2));
                }
            }
            for (int i = 1 ;i <= 12; i++) {
                MeterPower meterPower = new MeterPower();
                meterPower.setPaAdd("0.00");
                String key = i > 10 ? (i+""):("0"+i);
                meterPower.setMoth(key);
                if (meterMothMap.containsKey(key)) {
                    meterPower.setPaAdd(meterMothMap.get(key));
                }
                datas.add(meterPower);
            }
            results.put(sysItem.getItemName() + " " + sysItem.getItemAlias(), datas);
        }
        return results;
    }

    @Override
    public Map<String, Object[]> getFirstPageYearMeterPowers() throws Exception {
        List<String> meterTypes = Lists.newArrayList("5");
        QueryForm itemQuery = new QueryForm();
        itemQuery.setTypes(meterTypes);
        List<SysItem> sysItems = sysItemService.getMgItemSelect(itemQuery);
        if (CollectionUtils.isEmpty(sysItems)) {
            return Maps.newHashMap();
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String currentDay = simpleDateFormat.format(new Date());
        String currentMoth = currentDay.split("-")[1];
        String year =  currentDay.split("-")[0];
        List<MeterPower> meterPowers = meterPowerMapper.selectAllYearMeterPowers(year);


        Map<String, List<MeterPower>> meterPowerMap = Maps.newLinkedHashMap();
        for (MeterPower meterPower : meterPowers) {
            String key = meterPower.getSn();
            if (meterPowerMap.containsKey(key)) {
                meterPowerMap.get(key).add(meterPower);
            }else{
                List<MeterPower> list = Lists.newLinkedList();
                list.add(meterPower);
                meterPowerMap.put(key,list);
            }
        }

        Map<String, Object[]> results = Maps.newLinkedHashMap();
        results.put("meter",new String[4]);
        Double[] todays = new Double[]{0.0,0.0,0.0,0.0};
        Double[] moths = new Double[]{0.0,0.0,0.0,0.0};
        Double[] years = new Double[]{0.0,0.0,0.0,0.0};
        results.put("today",todays);
        results.put("moth",moths);
        results.put("year",years);
        int index = 0;

        for (SysItem sysItem : sysItems) {
            if(index == 4){
                break;
            }
            String sn = sysItem.getItemAlias();
            results.get("meter")[index] = sysItem.getItemName();
            List<MeterPower> yearDatas = meterPowerMap.get(sn);
            if(!CollectionUtils.isEmpty(yearDatas)){
                for(MeterPower meter:yearDatas){
                    String time1 = meter.getTime1();
                    String paAdd = meter.getPaAdd();
                    if(StringUtils.isEmpty(paAdd)){
                        continue;
                    }
                    double paAddNum = Double.parseDouble(paAdd);
                    if(BeiShuMap.containsKey(sysItem.getItemName())){
                        paAddNum = BeiShuMap.get(sysItem.getItemName())*paAddNum;
                    }
                    if(StringUtils.equals(time1,currentDay)){
                        double meter_index = (Double)results.get("today")[index]+paAddNum;
                        results.get("today")[index] =Double.parseDouble(NumberUtil.getPoint(meter_index,1)) ;
                    }
                    if(StringUtils.equals(meter.getMoth(),currentMoth)){
                        double meter_index = (Double)results.get("moth")[index]+paAddNum;
                        results.get("moth")[index] = Double.parseDouble(NumberUtil.getPoint(meter_index,1));
                    }
                    double meter_index = (Double)results.get("year")[index]+paAddNum;
                    results.get("year")[index] = Double.parseDouble(NumberUtil.getPoint(meter_index,1));
                }
            }
            ++index;
        }
        return results;
    }

    @Override
    public String updateMeterTestPower() throws Exception {
        MeterPowerExample sumExample = new MeterPowerExample();
        sumExample.setOrderByClause("time1 asc");
        List<MeterPower> meterPowers = meterPowerMapper.selectByExample(sumExample);
        Map<String, List<MeterPower>> meterPowerMap = Maps.newLinkedHashMap();
        for (MeterPower meterPower : meterPowers) {
            String key = meterPower.getSn();
            if (meterPowerMap.containsKey(key)) {
                meterPowerMap.get(key).add(meterPower);
            }else{
                List<MeterPower> list = Lists.newLinkedList();
                list.add(meterPower);
                meterPowerMap.put(key,list);
            }
        }
        List<MeterPowerInit> meterPowerInits = meterPowerMapper.selectLastMeterPower();
        Map<String, MeterPowerInit> powerInitMap = Maps.newHashMap();
        for (MeterPowerInit powerInit : meterPowerInits) {
            powerInitMap.put(powerInit.getSn(), powerInit);
        }
        for(String key:meterPowerMap.keySet()){
            List<MeterPower> powers = meterPowerMap.get(key);
            for(int i = 0;i < powers.size();i++){
                String paValue = "";
                MeterPower power = powers.get(i);
                if (i == 0) {
                    paValue = powerInitMap.get(power.getSn()).getValue1();
                }else {
                    paValue =  powers.get(i -1).getPa();
                    if(StringUtils.isEmpty(paValue)){
                        paValue =  powers.get(i -2).getPa();
                    }
                }
                if(StringUtils.isNotEmpty(paValue)&&StringUtils.isNotEmpty(power.getPa())){
                    double pa_d = Double.parseDouble(power.getPa()) - Double.parseDouble(paValue);
                    String paStr = NumberUtil.getPoint(pa_d, 2);
                    power.setPaAdd(paStr);
                }
            }
        }
        for(String key:meterPowerMap.keySet()){
            List<MeterPower> powers = meterPowerMap.get(key);
            for(int i = 0;i < powers.size();i++){
                MeterPower meterPower = powers.get(i);
                MeterPowerExample sumExample1 = new MeterPowerExample();
                sumExample1.createCriteria().andSnEqualTo(meterPower.getSn()).andTime1EqualTo(meterPower.getTime1());

                MeterPower update  = new MeterPower();
                update.setPaAdd(meterPower.getPaAdd());
                meterPowerMapper.updateByExampleSelective(update,sumExample1);
            }
        }
        return null;
    }
}
